// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: hyuan

#include "coin2/exchange/kucoin_futures/api_order/native_rest_async_asio_subscriber.h"

namespace coin2::exchange::kucoin_futures::api_order {

void KucoinFuturesRestAsyncAsioSubscriber::QueryBalance(const std::string& currency) {
  RestParams params;
  params.set_currency(currency);
  auto http_context = rest_client()->QueryAccountBalance(params);
  if (!http_context) return;
  http_context->handler =
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KucoinFuturesRestAsyncAsioSubscriber::QueryPosition() {
  RestParams params;
  auto http_context = rest_client()->QueryAccountPosition();
  if (!http_context) return;
  http_context->handler =
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KucoinFuturesRestAsyncAsioSubscriber::QueryOpenOrders() {
  auto http_context = rest_client()->QueryOpenOrders();
  if (!http_context) return;
  http_context->handler =
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KucoinFuturesRestAsyncAsioSubscriber::QueryHistoryOrders() {
  auto http_context = rest_client()->QueryHistoryOrders();
  if (!http_context) return;
  http_context->handler =
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KucoinFuturesRestAsyncAsioSubscriber::QueryFills() {
  auto http_context = rest_client()->QueryFills();
  if (!http_context) return;
  http_context->handler =
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KucoinFuturesRestAsyncAsioSubscriber::QueryBullet() {
  RestParams params;
  auto http_context = rest_client()->QueryBullet();
  if (!http_context) return;
  http_context->handler =
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KucoinFuturesRestAsyncAsioSubscriber::SubscribeAsync() {
  AddPeriodicTask(
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::QueryBullet, this),
      config_.query_account_balance_period_sec(),
      "query_bullet");

  std::set<std::string> native_currencies;
  for (const auto* currency : symcache_->GetCurrencies()) {
    native_currencies.emplace(currency->order_currency());
  }

  AddPeriodicTask(
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::QueryBalance, this, std::placeholders::_1),
      config_.query_account_balance_period_sec(),
      "query_balance",
      native_currencies);

  AddPeriodicTask(
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::QueryPosition, this),
      config_.query_account_position_period_sec(),
      "query_position");

  AddPeriodicTask(
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::QueryOpenOrders, this),
      config_.query_open_orders_period_sec(),
      "query_open_orders");

  AddPeriodicTask(
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::QueryHistoryOrders, this),
      config_.query_cancel_orders_period_sec(),
      "query_history_orders");

  AddPeriodicTask(
      std::bind(&KucoinFuturesRestAsyncAsioSubscriber::QueryFills, this),
      config_.query_fill_period_sec(),
      "query_fills");
}

}  // namespace coin2::exchange::kucoin_futures::api_order
